001 /* 002 * Copyright 2004-2005 Stephen McConnell 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.util; 020 021 import java.io.File; 022 import java.io.FileNotFoundException; 023 import java.io.InputStream; 024 import java.util.ArrayList; 025 import java.util.Properties; 026 027 import javax.xml.parsers.DocumentBuilder; 028 import javax.xml.parsers.DocumentBuilderFactory; 029 030 import org.w3c.dom.Document; 031 import org.w3c.dom.Element; 032 import org.w3c.dom.Node; 033 import org.w3c.dom.NodeList; 034 035 /** 036 * Utility class supporting the translation of DOM content into local child, children, 037 * attribute and value values. 038 * 039 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 040 * @version 1.0.2 041 */ 042 public final class ElementHelper 043 { 044 private ElementHelper() 045 { 046 // utility class 047 } 048 049 /** 050 * Return the root element of the supplied file. 051 * @param definition the file to load 052 * @return the root element 053 * @exception Exception if the error occurs during root element establishment 054 */ 055 public static Element getRootElement( final File definition ) 056 throws Exception 057 { 058 if( !definition.exists() ) 059 { 060 throw new FileNotFoundException( definition.toString() ); 061 } 062 063 if( !definition.isFile() ) 064 { 065 final String error = 066 "Source is not a file: " + definition; 067 throw new IllegalArgumentException( error ); 068 } 069 070 final DocumentBuilderFactory factory = 071 DocumentBuilderFactory.newInstance(); 072 factory.setValidating( false ); 073 factory.setNamespaceAware( false ); 074 final Document document = 075 factory.newDocumentBuilder().parse( definition ); 076 return document.getDocumentElement(); 077 } 078 079 /** 080 * Return the root element of the supplied input stream. 081 * @param input the input stream containing a XML definition 082 * @return the root element 083 * @exception Exception if an error occurs 084 */ 085 public static Element getRootElement( final InputStream input ) 086 throws Exception 087 { 088 final DocumentBuilderFactory factory = 089 DocumentBuilderFactory.newInstance(); 090 factory.setValidating( false ); 091 factory.setNamespaceAware( false ); 092 factory.setExpandEntityReferences( false ); 093 DocumentBuilder builder = factory.newDocumentBuilder(); 094 return getRootElement( builder, input ); 095 } 096 097 /** 098 * Return the root element of the supplied input stream. 099 * @param builder the document builder 100 * @param input the input stream containing a XML definition 101 * @return the root element 102 * @exception Exception if an error occurs 103 */ 104 public static Element getRootElement( final DocumentBuilder builder, final InputStream input ) 105 throws Exception 106 { 107 final Document document = builder.parse( input ); 108 return document.getDocumentElement(); 109 } 110 111 /** 112 * Return a named child relative to a supplied element. 113 * @param root the parent DOM element 114 * @param name the name of a child element 115 * @return the child element of null if the child does not exist 116 */ 117 public static Element getChild( final Element root, final String name ) 118 { 119 if( null == root ) 120 { 121 return null; 122 } 123 Element[] children = getChildren( root ); 124 for( int i=0; i<children.length; i++ ) 125 { 126 Element child = children[i]; 127 if( name.equals( child.getTagName() ) ) 128 { 129 return child; 130 } 131 } 132 return null; 133 } 134 135 /** 136 * Return all children matching the supplied element name. 137 * @param root the parent DOM element 138 * @param name the name against which child element will be matched 139 * @return the array of child elements with a matching name 140 */ 141 public static Element[] getChildren( final Element root, final String name ) 142 { 143 if( null == root ) 144 { 145 return new Element[0]; 146 } 147 Element[] children = getChildren( root ); 148 final ArrayList result = new ArrayList(); 149 for( int i=0; i<children.length; i++ ) 150 { 151 final Element child = children[i]; 152 if( name.equals( child.getTagName() ) ) 153 { 154 result.add( child ); 155 } 156 } 157 return (Element[]) result.toArray( new Element[0] ); 158 } 159 160 /** 161 * Return all children of the supplied parent. 162 * @param root the parent DOM element 163 * @return the array of all children 164 */ 165 public static Element[] getChildren( final Element root ) 166 { 167 if( null == root ) 168 { 169 return new Element[0]; 170 } 171 final NodeList list = root.getChildNodes(); 172 final int n = list.getLength(); 173 if( n < 1 ) 174 { 175 return new Element[0]; 176 } 177 final ArrayList result = new ArrayList(); 178 for( int i=0; i < n; i++ ) 179 { 180 final Node item = list.item( i ); 181 if( item instanceof Element ) 182 { 183 result.add( item ); 184 } 185 } 186 return (Element[]) result.toArray( new Element[0] ); 187 } 188 189 /** 190 * Return the value of an element. 191 * @param node the DOM node 192 * @return the node value 193 */ 194 public static String getValue( final Element node ) 195 { 196 if( null == node ) 197 { 198 return null; 199 } 200 String value; 201 if( node.getChildNodes().getLength() > 0 ) 202 { 203 value = node.getFirstChild().getNodeValue(); 204 } 205 else 206 { 207 value = node.getNodeValue(); 208 } 209 //return normalize( value ); 210 return value; 211 } 212 213 /** 214 * Return the value of an element attribute. 215 * @param node the DOM node 216 * @param key the attribute key 217 * @return the attribute value or null if the attribute is undefined 218 */ 219 public static String getAttribute( final Element node, final String key ) 220 { 221 return getAttribute( node, key, null ); 222 } 223 224 /** 225 * Return the value of an element attribute. 226 * @param node the DOM node 227 * @param key the attribute key 228 * @param def the default value if the attribute is undefined 229 * @return the attribute value or the default value if undefined 230 */ 231 public static String getAttribute( final Element node, final String key, final String def ) 232 { 233 if( null == node ) 234 { 235 return def; 236 } 237 if( !node.hasAttribute( key ) ) 238 { 239 return def; 240 } 241 //final String value = node.getAttribute( key ); 242 //return normalize( value ); 243 return node.getAttribute( key ); 244 } 245 246 /** 247 * Return the value of an element attribute as a boolean 248 * @param node the DOM node 249 * @param key the attribute key 250 * @return the attribute value as a boolean or false if undefined 251 */ 252 public static boolean getBooleanAttribute( final Element node, final String key ) 253 { 254 return getBooleanAttribute( node, key, false ); 255 } 256 257 /** 258 * Return the value of an element attribute as a boolean. 259 * @param node the DOM node 260 * @param key the attribute key 261 * @param def the default value if the attribute is undefined 262 * @return the attribute value or the default value if undefined 263 */ 264 public static boolean getBooleanAttribute( final Element node, final String key, final boolean def ) 265 { 266 if( null == node ) 267 { 268 return def; 269 } 270 271 if( !node.hasAttribute( key ) ) 272 { 273 return def; 274 } 275 276 String value = node.getAttribute( key ); 277 value = normalize( value ); 278 if( value.equals( "" ) ) 279 { 280 return def; 281 } 282 if( value.equalsIgnoreCase( "true" ) ) 283 { 284 return true; 285 } 286 if( value.equalsIgnoreCase( "false" ) ) 287 { 288 return false; 289 } 290 final String error = 291 "Boolean argument [" + value + "] not recognized."; 292 throw new IllegalArgumentException( error ); 293 } 294 295 /** 296 * Parse the value for any property tokens relative to system properties. 297 * @param value the value to parse 298 * @return the normalized string 299 */ 300 static String normalize( String value ) 301 { 302 return normalize( value, System.getProperties() ); 303 } 304 305 /** 306 * Parse the value for any property tokens relative to the supplied properties. 307 * @param value the value to parse 308 * @param props the reference properties 309 * @return the normalized string 310 */ 311 static String normalize( String value, Properties props ) 312 { 313 return PropertyResolver.resolve( props, value ); 314 } 315 }